package com.cocotingo.snail.dispatcher;

class ReusableThread {
	
	private int state;
	public static final int READY = 0;
	public static final int OCCUPOED = 1;
	public static final int DISPOSED = 2;
	
	private final Queue<Runnable> target;
	
	public ReusableThread() {
		this(Thread.NORM_PRIORITY);
	}
	
	public ReusableThread(int priority) {
		this(null, priority);
	}
	
	public ReusableThread(String name, int priority) {
		state = READY;
		target = new Queue<Runnable>();
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				Runnable runnable = null;
				try {
					while ((runnable = target.next()) != null) {
						runnable.run();
						synchronized (ReusableThread.this) {
							state = READY;
						}
					}
				} catch (InterruptedException e) {
					state = DISPOSED;
					throw new IllegalStateException("current thread was interrupted.", e);
				}
			}
		});
		if (name != null) t.setName(name);
		t.setPriority(priority);
		t.start();
	}
	
	public synchronized void execute(Runnable target) {
		if (state == READY) {
			this.target.append(target);
			state = OCCUPOED;
		} else {
			if (state == OCCUPOED)
				throw new IllegalStateException("ReusableThread is being used.");
			else
				throw new IllegalStateException("ReusableThread has already been disposed.");
		}
	}
	
	public synchronized void dispose() {
		if (state != DISPOSED) {
			this.target.append(null);
			state = DISPOSED;
		} else {
			throw new IllegalStateException("ReusableThread has already been disposed.");
		}
	}
	
	public synchronized int getState() {
		return state;
	}

}
